/**
 * @file libEink_Spetra6_render.h
 * @brief Defines for Spectra 6 render algorithm
 * @version v1.2.1
 * @date 2024-11-14
 * @author Joshua Yang
 * @copyright Copyright (C) 2024 E Ink Corporation
 */

#ifndef _EINK_Spactra6_RENDER_
#define _EINK_Spactra6_RENDER_

#if defined(__cplusplus)
extern "C"
{
#endif

#include <stdint.h>

    typedef enum
    {
        EINK_SUCCESS = 0,
        EINK_PANEL_SIZE_WRONG,
        EINK_FILE_OPEN_ERROR,
        EINK_FILE_SIZE_WRONG,
        EINK_FILE_CORRUPTION,
        EINK_COLOR_TYPE_WRONG,
        EINK_NOT_INITIAL,
        EINK_SYSYEM_FAILURE,
        EINK_IMAGE_FORMAT_WRONG,
        EINK_NOT_LOAD_AIE_LUT_YET,
        EINK_NOT_LOAD_VPCOA_LUT_YET,
        EINK_IMAGE_SIZE_WRONG,
        EINK_REGION_RECTAGLE_WRONG,
        EINK_PARAMETER_ERROR
    } EinkRenderErrMsg;

    typedef enum
    {
        EINK_RGB888,
        EINK_BGR888,
    } EinkImageFormat;

    typedef enum
    {
        EINK_FLOYD,
        EINK_FLOYD_SERPENTINE,
        EINK_JARVIS_JUDICE_NINKLE,
        EINK_JARVIS_JUDICE_NINKLE_SERPENTINE,
        EINK_STUCKI,
        EINK_STUCKI_SERPENTINE,
    } EinkDitheringMethod;

    /**
     * @brief Get the update log of this library.
     *
     * @return A pointer to a string containing the update log of the library.
     */
    char *Eink_get_updateLog();

    /**
     * @brief HSL image processing.
     *
     * @param[in] inputImg Pointer to the input image buffer.
     * @param[in] inputType The format of inputImg (RGB888 or BGR888).
     * @param[out] outputImg Pointer to the output image buffer.
     * @param[in] outputType The format of outputImg (RGB888 or BGR888).
     * @param[in] width The width of the image.
     * @param[in] height The height of the image.
     * @param[in] hue_offset Hue adjustment offset, in the range of 0 to 360.
     * @param[in] sat_offset Saturation adjustment offset, in the range of -100 to 100.
     * @param[in] bright_offset Brightness adjustment offset, in the range of -100 to 100.
     * @param[in] contrast_offset Contrast adjustment offset, in the range of -100 to 100.
     * @param[in] gamma Gamma adjustment factor, in the range of 0.0 to 2.0.
     *
     * @return EInk Error Message.
     */
    EinkRenderErrMsg Eink_image_adjustment(uint8_t *inputImg, EinkImageFormat inputType, uint8_t *outputImg, EinkImageFormat outputType, int width, int height, int hue_offset, int sat_offset, int bright_offset, int contrast_offset, double gamma);

    /**
     * @brief Initialize the Spectra6 render library.
     *
     * @warning Do not free the memory of fileBuffer after calling this function.
     *
     * @param[in] fileBuffer Pointer to the byte buffer containing the Look-Up-Table file.
     * @param[in] bufferSize The size of the fileBuffer, in bytes.
     *
     * @return EInk Error Message.
     */
    EinkRenderErrMsg Eink_Spectra6_render_init(uint8_t *fileBuffer, int bufferSize);

    /**
     * @brief Spectra6 render function for image processing.
     *
     * @warning Eink_Spectra6_render_init() must be called before using this function.
     *
     * @param[in] inputImg Pointer to the input image buffer.
     * @param[in] inputType The format of inputImg (RGB888 or BGR888).
     * @param[out] outputImg Pointer to the output image buffer.
     * @param[in] outputType The format of outputImg (RGB888 or BGR888).
     * @param[in] width The width of the image.
     * @param[in] height The height of the image.
     * @param[in] ditheringMethod The dithering method to be applied.
     * @param[in] mode_out Output mode:
     *              - 1: outputImg will be in the format of T1000.
     *              - 2: outputImg will be in the format of AOI IC.
     *              - 3: outputImg will be in the format of simulation.
     *
     * @return EInk Error Message.
     */
    EinkRenderErrMsg Eink_Spectra6_render(uint8_t *inputImg, EinkImageFormat inputType, uint8_t *outputImg, EinkImageFormat outputType, int width, int height, EinkDitheringMethod ditheringMethod, int mode_out);

    /**
     * @brief Spectra6 render function for image processing that outputs images in multiple formats.
     *
     * @warning Eink_Spectra6_render_init() must be called before using this function.
     *
     * @param[in] inputImg Pointer to the input image buffer.
     * @param[in] inputType The format of inputImg (RGB888 or BGR888).
     * @param[out] outputImgTCON Pointer to the output image buffer for TCON format.
     * @param[out] outputImgAIO Pointer to the output image buffer for AOI IC format.
     * @param[out] outputImgSimulation Pointer to the output image buffer for simulation format.
     * @param[in] outputType The format of output images (RGB888 or BGR888).
     * @param[in] width The width of the image.
     * @param[in] height The height of the image.
     * @param[in] ditheringMethod The dithering method to be applied.
     *
     * @return EInk Error Message.
     */
    EinkRenderErrMsg Eink_Spectra6_render_All(uint8_t *inputImg, EinkImageFormat inputType, uint8_t *outputImgTCON, uint8_t *outputImgAIO, uint8_t *outputImgSimulation, EinkImageFormat outputType, int width, int height, EinkDitheringMethod ditheringMethod);

    /**
     * @brief Convert the image format to align with the TFT arrangement.
     *
     * @param[in,out] image Pointer to the input image buffer in BGR888 or BGR888 format.
     * @param[in,out] pWidth Pointer to the width of the image.
     * @param[in,out] pHeight Pointer to the height of the image.
     * @param[in] mode TFT type option:
     *              - 1: Enable HGD with Source odd/even. Half Gate(Height) Double Source(Width).
     *              - 2: Enable HGD with Source even/odd. Half Gate(Height) Double Source(Width).
     *              - 3: Enable Swapping odd and even Gate.
     *              - 4: Enable HSD with Gate odd/even. Half Source(Width) Double Gate(Height).
     *              - 5: Enable HSD with Gate even/odd. Half Source(Width) Double Gate(Height).
     *
     * @return EInk Error Message.
     */
    EinkRenderErrMsg Eink_TFT_format_transfer(uint8_t *image, int *pWidth, int *pHeight, int mode);

#if defined(__cplusplus)
}
#endif

#endif